package session

import (
	"log"
	"sync"
	"time"
	"video_server/api/dbops"
	"video_server/api/defs"
	"video_server/api/utils"
)

// 并发 map
var sessionMap *sync.Map

// 会自动调用
// init 初始化一个 sessionMap
func init() {
	sessionMap = &sync.Map{}
}

// 获取毫秒
func nowInMilli() int64 {
	// 转换成毫秒， 因为获取的是 纳秒
	return time.Now().UnixNano() / 1000000
}

// 删除 session
func deleteExpiredSession(sid string) {
	sessionMap.Delete(sid)
	dbops.DeleteSessionID(sid)
}

// LoadSessionsFromDB 读取 DB 里面的sess ion
func LoadSessionsFromDB() {
	m, err := dbops.RetrieveAllSession()
	if err != nil {
		return
	}

	// 遍历
	m.Range(func(k, v interface{}) bool {
		ss := v.(*defs.SimpleSession)
		sessionMap.Store(k, ss)
		return true
	})

}

// GenerateNewSessionID 生成新的sessionId， 并返回 sessionId
func GenerateNewSessionID(un string) string {

	id := utils.NewGoUUID()

	// 转换成毫秒
	ct := nowInMilli()
	ttl := ct * 30 * 60 * 1000 // 把生成的毫秒数，转换成 30 min

	ss := &defs.SimpleSession{Username: un, TTL: ttl}
	sessionMap.Store(id, ss)
	err := dbops.InsertSession(id, ttl, un)
	if err != nil {
		log.Printf("创建用户 session 生成失败！, %s", err)
	}

	return id
}

// IsSessionExpired 判断sessionId是否过期
// 返回值：string 是sessionId, bool 表示是否过期
func IsSessionExpired(sid string) (string, bool) {

	ss, ok := sessionMap.Load(sid)
	if ok {
		// 转换成毫秒
		ct := nowInMilli()
		if ss.(*defs.SimpleSession).TTL < ct {
			// 删除失效的session
			deleteExpiredSession(sid)
			return "", true
		}

		return ss.(*defs.SimpleSession).Username, false
	}

	return "", true
}
